﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject.Core;
using Hotnet.Dal.NSDalVideo;
using Hotnet.Entity;
using Hotnet.Dal.NSDalCommon;
using Hotnet.Biz.NSBizCommon;
using Hotnet.Entity.Enum;
using Hotnet.Entity.Search;
using Hotnet.Entity.View;

namespace Hotnet.Biz.NSBizVideo
{
	public class BizVideo:BaseBiz<Video>
	{
		private static DalVideo db = new DalVideo();
		private static BizTag bizTag = new BizTag();
		private static BizVideoXTag bizVideoXTag = new BizVideoXTag();
		private static BizCastCharacter bizCastCharacter = new BizCastCharacter();
		private static BizVideoAndVideoGroupCommon bizCommon = new BizVideoAndVideoGroupCommon();
		private static BizVideoChild bizVideoChild = new BizVideoChild();
		private static BizSourceFrom bizSourceFrom = new BizSourceFrom();
		private static Video[] emptyVideo=new Video[0];

		public BizVideo() : base(db) { }


		public ViewListVideo[] List(int pageNo, int pageSize, out int totalCount, SearchVideoCondition searchObj,int? isPublished)
		{
			return db.List(pageNo,pageSize,out totalCount,searchObj,isPublished);
		}

		/// <summary>
		/// 按照各大网站分组列出焦点
		/// </summary>
		/// <param name="startDate"></param>
		/// <param name="endDate"></param>
		/// <param name="defineType"></param>
		/// <returns></returns>
		public IEnumerable<IGrouping<int, ViewVideoList>> ListTopXEveryNet(EnumVideoListType listType, int topNumber)
		{
			ViewVideoList[] videos = db.ListTopXEveryNet(topNumber, listType);
			IEnumerable<IGrouping<int, ViewVideoList>> groupResult = videos.GroupBy<ViewVideoList, int>(x => x.SourceFromID.Value);
			return groupResult;
		}

		/// <summary>
		/// 列出我的推荐
		/// </summary>
		/// <returns></returns>
		public Video[] ListMyCommendVideoes(int number,EnumOrder order)
		{
			return db.ListDefineTypeVideoes(number, EnumDefineType.我的推荐,order);
		}

		/// <summary>
		/// 列出我的推荐,某一个视频分类下面的推荐
		/// </summary>
		/// <returns></returns>
		public Video[] ListMyCommendVideoes(int categoryID)
		{
			return db.ListDefineTypeVideoes(6, EnumDefineType.我的推荐, categoryID, EnumOrder.添加时间);
		}

		/// <summary>
		/// 列出最热的视频
		/// </summary>
		/// <param name="number"></param>
		/// <returns></returns>
		public Video[] ListHotVideo()
		{
			return db.ListHotVideo(9);
		}

		/// <summary>
		/// 列出头条的video
		/// </summary>
		/// <returns></returns>
		public Video[] ListHeadVideoes()
		{
			return db.ListDefineTypeVideoes(5, EnumDefineType.首页轮换, EnumOrder.添加时间);
		}

		/// <summary>
		/// 列出最新的视频
		/// </summary>
		/// <param name="number"></param>
		/// <returns></returns>
		public Video[] ListLatestVideo()
		{
			return db.ListLatestVideo(6);
		}

		/// <summary>
		/// 列出每个分类的大眼睛视频
		/// </summary>
		/// <param name="number"></param>
		/// <param name="order"></param>
		/// <returns></returns>
		public Video[] ListCategoryEyeVideos(int categoryId,int number, EnumOrder order)
		{
			return db.ListDefineTypeVideos(categoryId,number, EnumDefineType.分类轮换, EnumOrder.点击次数);
		}

		/// <summary>
		/// 列出历史点击次数的视频,近一天,近一周,近一月...
		/// </summary>
		/// <param name="topNumber"></param>
		/// <returns></returns>
		public IEnumerable<IGrouping<int, VideoHistoryHot>> ListVideoHistoryHot(int topNumber)
		{
			VideoHistoryHot[] videos=db.ListVideoHistoryHot(topNumber);
			IEnumerable<IGrouping<int, VideoHistoryHot>> groupResult = videos.GroupBy<VideoHistoryHot, int>(x => x.VideoTimeSpan);
			return groupResult;
		}

		/// <summary>
		/// 列出视频分类点击靠前的视频,
		/// </summary>
		/// <param name="topNumber">top 数</param>
		/// <returns></returns>
		public IEnumerable<IGrouping<int, Video>> ListTopXVideoByCategory(int topNumber)
		{
			Video[] videos = db.ListTopXVideoByCategory(topNumber);
			IEnumerable<IGrouping<int, Video>> groupResult = videos.GroupBy<Video, int>(x => x.CategoryID.Value);
			return groupResult;
		}

		

		public void Update(string tags,string castCharacters,Video model)
		{
			//删除原有的tag与video得关联
			bizVideoXTag.Delete(model.VideoID);
			bizCommon.InsertVideoTags(tags, model.VideoID);
			//删除原有castCharacters 关联
			bizCastCharacter.Delete(model.VideoID);
			//添加现有的castCharacters关联
			bizCommon.InsertCastCharacters(castCharacters, model.VideoID);
			Video origialMode = Get(model.VideoID);
			//删除原有的封面
			if (!string.IsNullOrEmpty(model.CoverImagePath) && origialMode.CoverImagePath != model.CoverImagePath)
				if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + origialMode.CoverImagePath))
					System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + origialMode.CoverImagePath);

			db.Update(model);
		}

		public int Insert(string tags, string castCharacters,Video model)
		{
			db.Insert(model);
			if (model.VideoID == 0)
				return 0;
			bizCommon.InsertVideoTags(tags, model.VideoID);
			bizCommon.InsertCastCharacters(castCharacters, model.VideoID);
			

			return model.VideoID;
		}

		public new bool Delete(int id)
		{
			Video video = db.Get(id);
			if (video != null)
			{
				//删除Tag的关联表数据
				bizVideoXTag.Delete(id);
				//删除演员的关联表数据
				bizCastCharacter.Delete(id);
				//删除video
				base.Delete(id);
				//删除封面图片
				if (!string.IsNullOrEmpty(video.CoverImagePath))
					if(System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + video.CoverImagePath))
						System.IO.File.Delete(AppDomain.CurrentDomain.BaseDirectory + video.CoverImagePath);
				return true;
			}
			return false;
		}

		/// <summary>
		/// 删除视频组
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public bool DeleteVideoGroup(int id)
		{
			//删除视频组下面的子视频
			bizVideoChild.DeleteByGroupID(id);
			//删除自身
			this.Delete(id);
			return true;
		}

		/// <summary>
		/// 根据tagids 到video 和videoGroup查找相关视频或者视频组,此处要考虑被下面根据TagName的方法替换，此方法只提供video分类使用
		/// </summary>
		/// <param name="tagIds"></param>
		/// <returns></returns>
		public Video[] ListReferenceVideoByTags(int[] tagIds, int number, bool isWhenNotEnoughAdd)
		{
			//TODO 考虑被下面根据TagName的方法替换
			return isWhenNotEnoughAdd ? db.VideoSupplyWhenNotEnough(db.ListTopXVideoByTags(tagIds, number),number) : db.ListTopXVideoByTags(tagIds, number);
		}

		/// <summary>
		/// 按照类型和网站来源列出本月的视频每日的数量
		/// </summary>
		/// <param name="sourceFromId"></param>
		/// <returns></returns>
		public VideoDayCount[] ListVideoCountByMonth(int[] sourceFromIds, EnumDefineType defineType,DateTime dayInMonth)
		{
			if (sourceFromIds.Length == 1 && sourceFromIds[0] == 0)
				sourceFromIds = bizSourceFrom.List(EnumSystemCategory.视频).Select(x => x.SourceFromID).ToArray();
			return db.ListVideoCountByMonth(sourceFromIds, defineType, dayInMonth);
		}

		/// <summary>
		/// 根据sourceFromId 和 网站定义列表 和 日期 列出video，不分页
		/// </summary>
		/// <param name="sourceFromIds"></param>
		/// <param name="defineType"></param>
		/// <param name="begin"></param>
		/// <param name="end"></param>
		/// <returns></returns>
		public Video[] ListVideoByNetAndDate(int[] sourceFromIds, EnumDefineType defineType, DateTime begin, DateTime end)
		{
			if (sourceFromIds.Length == 1 && sourceFromIds[0] == 0)
				sourceFromIds = bizSourceFrom.List(EnumSystemCategory.视频).Select(x=>x.SourceFromID).ToArray();
			return db.ListVideoByNetAndDate(sourceFromIds, defineType, begin, end);
		}

		public DateTime GetLatestVideoTime(EnumDefineType defineType)
		{
			return db.ListBy<DateTime>(x => x.DefineType == (int)defineType, x => x.AddTime, true).First().AddTime;
		}

		/// <summary>
		/// 根据TagName 查询 video
		/// </summary>
		/// <param name="tagName"></param>
		/// <returns></returns>
		public Video[] ListReferenceVideoByTags(int pageNo, int pageSize, out int totalCount, SearchByTagConditon searchObj)
		{
			if (string.IsNullOrEmpty(searchObj.TagName))
			{
				totalCount = 0;
				return emptyVideo;
			}
			return db.ListVideoByTag(pageNo, pageSize, out totalCount, searchObj);
		}

		/// <summary>
		/// 根据tag 获得相关视频
		/// </summary>
		/// <param name="tags"></param>
		/// <param name="count"></param>
		/// <param name="isWhenNotEnoughAdd"></param>
		/// <returns></returns>
		public Video[] ListReferenceVideoByTags(string tags, int count, bool isWhenNotEnoughAdd)
		{
			SearchByTagConditon s = new SearchByTagConditon() { TagName=tags };
			int tempCount = 0;
			return isWhenNotEnoughAdd ? db.VideoSupplyWhenNotEnough(ListReferenceVideoByTags(0, count, out tempCount, s),count) : ListReferenceVideoByTags(0, count, out tempCount, s);
		}

		/// <summary>
		/// 根据tag 获得相关视频
		/// </summary>
		/// <param name="tags"></param>
		/// <param name="count"></param>
		/// <param name="isWhenNotEnoughAdd"></param>
		/// <returns></returns>
		public Video[] ListReferenceVideoByTags(IList<string> tags, int count, bool isWhenNotEnoughAdd)
		{
			string strTag = string.Join(" ", tags.ToArray());
			return ListReferenceVideoByTags(strTag, count, isWhenNotEnoughAdd);
		}


	}
}
